<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>quarkus - 上手练习</title>
    <script src="https://cdn.tailwindcss.com/3.3.1"></script>
    <script src="https://unpkg.com/axios@1.3.6"></script>
    <script src="https://unpkg.com/vue@3.2.47"></script>
    <script src="https://unpkg.com/naive-ui@2.34.3"></script>
    <style>
        .bg {
            background-color: #F5F5F5;
        }
        .bg-message {
            background-color: #FFFFFF;
            color: rgb(51 65 85);
        }
    </style>
</head>
<body>
<div id="app">
    <div class="mx-auto sm:w-4/5 lg:w-3/5 xl:w-1/2">
        <div class="flex flex-col h-screen bg">
            <div class="grow">
                <message v-for="item in messageList" :text="item.text" :avatar="item.avatar" />
            </div>
            <div><n-divider /></div>
            <div class="p-2 flex justify-between items-end">
                <div class="flex-grow mr-2 flex flex-col justify-end">
                    <n-input v-model:value="message" type="textarea" placeholder="说点什么..." />
                </div>
                <div>
                    <n-button v-if="token" @click="onSend" :loading="sending">发送</n-button>
                    <n-button v-else @click="loginVisible = true">登录</n-button>
                </div>
            </div>

        </div>

        <n-modal v-model:show="loginVisible" :mask-closable="false">
            <n-card style="width: 400px">
                <n-form-item label="账号">
                    <n-input v-model:value="username" placeholder="请输入" />
                </n-form-item>
                <n-form-item label="密码">
                    <n-input v-model:value="password" type="password" placeholder="请输入" />
                </n-form-item>
                <div class="mb-2"><n-button block @click="onLogin">立即登录</n-button></div>
                <div class="mb-2"><n-button block @click="onRegister">立即注册</n-button></div>
                <n-button block type="tertiary" @click="loginVisible = false">取消</n-button>
            </n-card>
        </n-modal>

    </div>
</div>
<script>
    const TOAST = naive.createDiscreteApi(['message']).message
    const App = {
        setup() {
            return {
                message: Vue.ref(''),
                messageList: Vue.ref([]),
                token: Vue.ref(''),
                loginVisible: Vue.ref(false),
                username: Vue.ref('user'),
                password: Vue.ref('123456'),
                sending: Vue.ref(false),
            }
        },
        methods: {
            pushMessage(text, isSend) {
                this.messageList.push({
                    avatar: isSend ? '/static/user.jpg' : '/static/gpt.jpg',
                    text: text,
                })
            },
            onSend() {
                this.pushMessage(this.message, true)
                this.postMessage()
            },
            // 请求聊天API
            postMessage() {
                const data = {
                    text: this.message
                }
                this.message = ''
                this.sending = true
                this.post('/api/chat', data)
                    .then(resp => {
                        console.log(resp)
                        this.pushMessage(resp.data.text)
                    })
                    .finally(() => this.sending = false)
            },
            onLogin() {
                if (!this.username || !this.password) {
                    TOAST.warning('请输入账号和密码')
                    return
                }
                const data = {
                    username: this.username,
                    password: this.password
                }
                this.post('/api/member/login', data)
                    .then(resp => {
                        this.token = resp.data
                        this.loginVisible = false
                    })
            },
            onRegister() {
                if (!this.username || !this.password) {
                    TOAST.warning('请输入账号和密码')
                    return
                }
                const data = {
                    username: this.username,
                    password: this.password
                }
                this.post('/api/member/register', data)
                    .then(resp => {
                        TOAST.success('注册成功，请点击登录')
                    })
            },
            post(url, data) {
                return new Promise((resolve, reject) => {
                    const options = {}
                    if (this.token) {
                        options.headers = {
                            'Authorization': 'Bearer ' + this.token
                        }
                    }
                    window.axios.post(url, data, options)
                        .then(response => {
                            const resp = response.data
                            if (resp.status === 200) {
                                resolve(resp)
                            } else {
                                TOAST.error(resp.message)
                                reject(new Error(resp.message))
                            }
                        })
                        .catch(err => {
                            try {
                                TOAST.error(err.response.data.message)
                            } catch (e) {
                                TOAST.error(err.message)
                            }
                            reject(err)
                        })
                })
            }
        },
    }
    const app = Vue.createApp(App)
    app.use(naive)
    // 自定义消息组件
    app.component('message', {
        props: ['avatar', 'text'],
        template: `
          <div class="p-2 flex">
              <div><n-avatar :src="avatar"></n-avatar></div>
              <div class="ml-2 p-2 flex-grow break-all bg-message" style="max-width: 100%;">{{text}}</div>
          </div>
        `
    })
    app.mount('#app')
</script>
</body>
</html>